From 7fe628f7de67c79d8934612644c27b17eb95e228 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 7 Oct 2003 21:27:25 +0000 Subject: [PATCH] bitkeeper revision 1.491 (3f832fbdOKWxUmK2ZYQ1DMaJhGFEwA) desc.h, memory.c, process.c, mm.c: Fix up memory-management security checking. --- xen/arch/i386/mm.c | 7 ++++--- xen/arch/i386/process.c | 9 +++++++++ xen/common/memory.c | 7 +++++-- xen/include/asm-i386/desc.h | 12 +++++------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/xen/arch/i386/mm.c b/xen/arch/i386/mm.c index 4c812e849f..cac87b6ef2 100644 --- a/xen/arch/i386/mm.c +++ b/xen/arch/i386/mm.c @@ -129,9 +129,10 @@ long do_stack_switch(unsigned long ss, unsigned long esp) int nr = smp_processor_id(); struct tss_struct *t = &init_tss[nr]; - if ( !VALID_DATASEL(ss) ) - return -EINVAL; - + /* + * No need to check validity: CPU will fault if SS or ESP is bad. This is + * true even for a fast trap: a bad SS:ESP will get us either a #SS or #TS. + */ current->thread.ss1 = ss; current->thread.esp1 = esp; t->ss1 = ss; diff --git a/xen/arch/i386/process.c b/xen/arch/i386/process.c index d7bc386adc..49f45688c6 100644 --- a/xen/arch/i386/process.c +++ b/xen/arch/i386/process.c @@ -253,6 +253,15 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) &next_p->shared_info->execution_context, sizeof(*stack_ec)); + /* + * This is sufficient! If the descriptor DPL differs from CS RPL + * then we'll #GP. If DS, ES, FS, GS are DPL 0 then they'll be + * cleared automatically. If SS RPL or DPL differs from CS RPL + * then we'll #GP. + */ + if ( (stack_ec->cs & 3) == 0 ) + stack_ec->cs = 0; + unlazy_fpu(prev_p); /* Switch the fast-trap handler. */ diff --git a/xen/common/memory.c b/xen/common/memory.c index ecb3a30919..c4ca379817 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -816,12 +816,15 @@ int do_process_page_updates(page_update_request_t *ureqs, int count) case PGT_l2_page_table: err = mod_l2_entry((l2_pgentry_t *)req.ptr, mk_l2_pgentry(req.val)); - break; - default: + break; + case PGT_none: MEM_LOG("Update to non-pt page %08lx", req.ptr); *(unsigned long *)req.ptr = req.val; err = 0; break; + default: + MEM_LOG("Update to bad page %08lx", req.ptr); + break; } } else diff --git a/xen/include/asm-i386/desc.h b/xen/include/asm-i386/desc.h index c3b01d69d5..780f9c8728 100644 --- a/xen/include/asm-i386/desc.h +++ b/xen/include/asm-i386/desc.h @@ -14,21 +14,19 @@ #define load_TR(n) __asm__ __volatile__ ("ltr %%ax" : : "a" (__TSS(n)<<3) ) /* - * Guest OS must provide its own code selectors, or use the one we provide. - * The RPL must be 1, as we only create bounce frames to ring 1. - * Any LDT selector value is okay. + * Guest OS must provide its own code selectors, or use the one we provide. The + * RPL must be 1, as we only create bounce frames to ring 1. Any LDT selector + * value is okay. Note that checking only the RPL is insufficient: if the + * selector is poked into an interrupt, trap or call gate then the RPL is + * ignored when the gate is accessed. */ - #define VALID_SEL(_s) \ (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) || \ (((_s)>>3) > LAST_RESERVED_GDT_ENTRY) || \ ((_s)&4)) && \ (((_s)&3) == 1)) - #define VALID_CODESEL(_s) ((_s) == FLAT_RING1_CS || VALID_SEL(_s)) -#define VALID_DATASEL(_s) ((_s) == FLAT_RING1_DS || VALID_SEL(_s)) - /* These are bitmasks for the first 32 bits of a descriptor table entry. */ #define _SEGMENT_TYPE (15<< 8) #define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */ -- 2.30.2